﻿namespace NTLib.Core.Threading
{
    using NTLib.Core.Memory;
    using System;
    using System.Threading;
    using System.Threading.Tasks;

    /// <summary>
    /// Used to synchronize the access to different resources
    /// </summary>
    public interface ILocker : IDisposableExt
    {
        #region Methods

        /// <summary>
        /// Locks the specified access.
        /// </summary>
        /// <param name="read">if set to <c>true</c> the acces will be lock for read depend of the locker item used.</param>
        void Lock(bool read = false);

        /// <summary>
        /// Locks the specified access.
        /// </summary>
        /// <param name="read">if set to <c>true</c> the acces will be lock for read depend of the locker item used.</param>
        IDisposable ScopeLock(bool read = false);

        /// <summary>
        ///  Locks the specified access.
        /// </summary>
        /// <param name="read">if set to <c>true</c> the acces will be lock for read depend of the locker item used.</param>
        /// <param name="token">The token.</param>
        Task LockAsync(bool read = false, CancellationToken token = default(CancellationToken));

        /// <summary>
        ///  Locks the specified access.
        /// </summary>
        /// <param name="read">if set to <c>true</c> the acces will be lock for read depend of the locker item used.</param>
        /// <param name="token">The token.</param>
        Task<IDisposable> ScopeLockAsync(bool read = false, CancellationToken token = default(CancellationToken));

        /// <summary>
        /// Releases the specified access.
        /// </summary>
        /// <param name="fromRead">if set to <c>true</c> the acces will be lock from read depend of the locker item used.</param>
        void Release(bool fromRead = false);

        #endregion
    }
}
